#if defined(TSINGMA_MX) || defined(TSINGMA_GX) || defined(ARCTIC)
/**
 @file sys_tmm_security.c

 @date 2019-3-14

 @version v1.0

 The file contains TMM policer APIs of sys layer
*/

/***************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "sal.h"
#include "ctc_error.h"
#include "ctc_debug.h"

#include "sys_usw_common.h"
#include "sys_usw_security.h"


#include "drv_api.h"

int32
sys_tmm_storm_ctl_get_profile_from_hw(uint8 lchip, uint32 stmctl_offset,
                        void* p_cfg, void* p_profile_param)
{
    uint32 cmd = 0;
    DsIpeStormCtl0ConfigE_m stmctl_cfgE;
    DsIpeStormCtl0ProfileX_m stmctl_profile;
    ctc_security_stmctl_cfg_t* p_stmctl_cfg = (ctc_security_stmctl_cfg_t*) p_cfg;
    sys_stmctl_profile_t* p_profile = (sys_stmctl_profile_t*) p_profile_param;
    uint32 confE_tbl_id[2] = {DsIpeStormCtl0ConfigE_t,DsIpeStormCtl1ConfigE_t};
    uint32 prof_tbl_id[2][2] = {{DsIpeStormCtl0ProfileX_t,DsIpeStormCtl0ProfileY_t},
                                {DsIpeStormCtl1ProfileX_t,DsIpeStormCtl1ProfileY_t}};
    uint8  tbl_resrc_id = 0;
    uint8  tbl_index_id = 0; 

    SYS_SECURITY_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    sal_memset(&stmctl_cfgE, 0, sizeof(DsIpeStormCtl0ConfigE_m));
    sal_memset(&stmctl_profile, 0, sizeof(DsIpeStormCtl0ProfileX_m));

    SYS_STMCTL_GET_TBL_RESRC_ID(p_stmctl_cfg->op, stmctl_offset, tbl_resrc_id);
    SYS_STMCTL_GET_TBL_INDEX_ID(stmctl_offset, tbl_index_id);
    cmd = DRV_IOR(confE_tbl_id[tbl_resrc_id], DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, tbl_index_id, DRV_CMD_PP_EN(cmd), &stmctl_cfgE));
    if(stmctl_offset & 0x1)
    {
        p_profile->profile_id = GetDsIpeStormCtl0ConfigE(V, profIdY_f, &stmctl_cfgE);
        if(p_profile->profile_id)
        {
            cmd = DRV_IOR(prof_tbl_id[tbl_resrc_id][1], DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_profile->profile_id, DRV_CMD_PP_EN(cmd), &stmctl_profile));
        }
    }
    else
    {
        p_profile->profile_id = GetDsIpeStormCtl0ConfigE(V, profIdX_f, &stmctl_cfgE);
        if(p_profile->profile_id)
        {
            cmd = DRV_IOR(prof_tbl_id[tbl_resrc_id][0], DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_profile->profile_id, DRV_CMD_PP_EN(cmd), &stmctl_profile));
        }
    }

    if(p_profile->profile_id)
    {
        p_profile->is_y       = stmctl_offset & 0x1;
        p_profile->op         = tbl_resrc_id;
        p_profile->rate       = GetDsIpeStormCtl0ProfileX(V, rate_f, &stmctl_profile);
        p_profile->rate_shift = GetDsIpeStormCtl0ProfileX(V, rateShift_f, &stmctl_profile);
        p_profile->rate_frac  = GetDsIpeStormCtl0ProfileX(V, rateFrac_f, &stmctl_profile);
        p_profile->threshold  = GetDsIpeStormCtl0ProfileX(V, threshold_f, &stmctl_profile);
        p_profile->threshold_shift = GetDsIpeStormCtl0ProfileX(V, thresholdShift_f, &stmctl_profile);
    }

    return CTC_E_NONE;
}

int32
sys_tmm_storm_ctl_add_hw(uint8 lchip, uint32 stmctl_offset,
                void* p_cfg, void* p_profile_param,uint8 is_add)
{
    uint8  is_pps = 0;
    uint8  tbl_resrc_id = 0;
    uint8  tbl_index_id = 0;
    uint32 cmd = 0;
    DsIpeStormCtl0Config_m stmctl_cfg;
    DsIpeStormCtl0ConfigE_m stmctl_cfgE;
    DsIpeStormCtl0ProfileX_m stmctl_profile;
    ctc_security_stmctl_cfg_t* p_stmctl_cfg = (ctc_security_stmctl_cfg_t*) p_cfg;
    sys_stmctl_profile_t* p_profile = (sys_stmctl_profile_t*) p_profile_param;
    uint32 conf_tbl_id[2] = {DsIpeStormCtl0Config_t,DsIpeStormCtl1Config_t};
    uint32 confE_tbl_id[2] = {DsIpeStormCtl0ConfigE_t,DsIpeStormCtl1ConfigE_t};
    uint32 prof_tbl_id[2][2] = {{DsIpeStormCtl0ProfileX_t,DsIpeStormCtl0ProfileY_t},
                                {DsIpeStormCtl1ProfileX_t,DsIpeStormCtl1ProfileY_t}};

    SYS_SECURITY_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    sal_memset(&stmctl_cfg, 0, sizeof(DsIpeStormCtl0Config_m));
    sal_memset(&stmctl_cfgE, 0, sizeof(DsIpeStormCtl0ConfigE_m));
    sal_memset(&stmctl_profile, 0, sizeof(DsIpeStormCtl0ProfileX_m));

    SYS_STMCTL_GET_TBL_RESRC_ID(p_stmctl_cfg->op, stmctl_offset, tbl_resrc_id);
    SYS_STMCTL_GET_TBL_INDEX_ID(stmctl_offset, tbl_index_id);
    if(CTC_SECURITY_STORM_CTL_MODE_PPS == p_stmctl_cfg->mode
        || CTC_SECURITY_STORM_CTL_MODE_KPPS == p_stmctl_cfg->mode)
    {
        is_pps = 1;
    }

    if(is_add)
    {
       SetDsIpeStormCtl0ProfileX(V, ppsShift_f,  &stmctl_profile, 7);   /**/
       SetDsIpeStormCtl0ProfileX(V, rate_f,      &stmctl_profile, p_profile->rate);
       SetDsIpeStormCtl0ProfileX(V, rateMaxShift_f, &stmctl_profile, 0xF);
       SetDsIpeStormCtl0ProfileX(V, rateMax_f,  &stmctl_profile, 0xFFFF);
       SetDsIpeStormCtl0ProfileX(V, rateShift_f, &stmctl_profile, p_profile->rate_shift);
       SetDsIpeStormCtl0ProfileX(V, rateFrac_f,  &stmctl_profile, p_profile->rate_frac);
       SetDsIpeStormCtl0ProfileX(V, threshold_f,  &stmctl_profile, p_profile->threshold);
       SetDsIpeStormCtl0ProfileX(V, thresholdShift_f,  &stmctl_profile, p_profile->threshold_shift);
       if(stmctl_offset & 0x1)
       {
           cmd = DRV_IOW(prof_tbl_id[tbl_resrc_id][1], DRV_ENTRY_FLAG);
       }
       else
       {
           cmd = DRV_IOW(prof_tbl_id[tbl_resrc_id][0], DRV_ENTRY_FLAG);
       }
       CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_profile->profile_id, DRV_CMD_PP_EN(cmd), &stmctl_profile));
    }

    /*write hw -- config*/
    cmd = DRV_IOR(conf_tbl_id[tbl_resrc_id], DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, tbl_index_id, DRV_CMD_PP_EN(cmd), &stmctl_cfg));

    cmd = DRV_IOR(confE_tbl_id[tbl_resrc_id], DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, tbl_index_id, DRV_CMD_PP_EN(cmd), &stmctl_cfgE));
    if(stmctl_offset & 0x1)
    {
        SetDsIpeStormCtl0Config(V, exceptionEnY_f, &stmctl_cfg,is_add? p_stmctl_cfg->discarded_to_cpu:0);
        SetDsIpeStormCtl0ConfigE(V, conf_ppsModeY_f,     &stmctl_cfgE, is_add?is_pps:0);
        SetDsIpeStormCtl0ConfigE(V, profIdY_f, &stmctl_cfgE, is_add?p_profile->profile_id:0);
    }
    else
    {
        SetDsIpeStormCtl0Config(V, exceptionEnX_f, &stmctl_cfg, is_add? p_stmctl_cfg->discarded_to_cpu:0);
        SetDsIpeStormCtl0ConfigE(V, conf_ppsModeX_f,     &stmctl_cfgE, is_add?is_pps:0);
        SetDsIpeStormCtl0ConfigE(V, profIdX_f, &stmctl_cfgE,is_add?p_profile->profile_id:0);
    }
    cmd = DRV_IOW(conf_tbl_id[tbl_resrc_id], DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, tbl_index_id, DRV_CMD_PP_EN(cmd), &stmctl_cfg));

    cmd = DRV_IOW(confE_tbl_id[tbl_resrc_id], DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, tbl_index_id, DRV_CMD_PP_EN(cmd), &stmctl_cfgE));

    SYS_SECURITY_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "op=%d,isY=%d,tbl_id=%d,prof_id=%d\n",p_stmctl_cfg->op, stmctl_offset&0x1,
                            tbl_index_id, p_profile->profile_id);
    return CTC_E_NONE;
}
#endif

